﻿// OssJsonTest.cpp : 定义控制台应用程序的入口点。
//

#include <json/ossJson.h>
#include <ossString.h>
#include <ossTime.h>
#include <ossStdlib.h>
#include <json/ossJson.h>
#include <crtdbg.h>

void Test1()
{
	OssJson json;

	int iError = json.ParseJson("{}");
	if (iError == 0)
	{
		printf("解析成功\n");
	}
	else
	{
		printf("解析失败 %d\n",iError);
	}
}

void Test2_kv()
{
	OssJson json;

	int iError = json.ParseJson("{k:v}");
	if (json["k"] == "v")
	{
		printf("测试通过 k = v\n");
	}
	else
	{
		printf("解析错误 %d\n",iError);
	}
}

Bool g_printSussess = TRUE;

Bool CheckJson(char* pcJson,char* pValidateJson,Bool expeceRes = TRUE)
{
	OssJson json;
	int iError = json.ParseJson(pcJson);
	if (iError != 0)
	{
		if (expeceRes)
		{
			printf("解析错误 %d:%s\n",iError,pcJson);
			return FALSE;
		}
		else
		{
			if (g_printSussess)
			{
				printf("符合预期，解析失败\n");
			}

			return TRUE;
		}
	}
	
	char acResultJson[4096];
	json.ToJsonString(acResultJson,sizeof(acResultJson));
	if (OssStrcmp(acResultJson,pValidateJson) != 0)
	{
		printf("解析出来的结果不符合要求:\n\t%s\n\t%s\n",pcJson,acResultJson);
		return FALSE;
	}

	if (g_printSussess)
	{
		printf("解析成功:\n\t%s\n\t%s\n",pcJson,acResultJson);
	}
	
	return TRUE;
}

#define TEST_COUNT		10000
void PerformanceTesting(char* pcJson)
{
	DWord dwTick = OssGetTickCount();
	for (int i=0;i<TEST_COUNT;i++)
	{
		OssJson json;
		json.ParseJson(pcJson);
	}
	dwTick = OssGetTickCount() - dwTick;

	printf("执行 %d 次 Json解析，总计耗时%dms\n",TEST_COUNT,dwTick);
}

Bool JsonOperatorTest(char* pcJson)
{
	OssJson root;

	root.ParseJson(pcJson);

	//验证消息合法性
	OssJson &msgId = root["msgId"];
	OssJson &transactionId = root["transactionId"];
	OssJson &deviceId = root["deviceId"];

	if ((msgId.ValueType() != JSON_STRING_VAL) ||
		(transactionId.ValueType() != JSON_STRING_VAL) ||
		(deviceId.ValueType() != JSON_STRING_VAL) )
	{
		printf("UeInfoManage::ParseUeInfo json msg is error\n");
		return FALSE;
	}

	//解析出消息放入结构体
	if (OssStrcmp((char*)msgId.asCString(), "imsiReport") != 0)
	{
		printf("不是指定的消息:%s/%s\n",msgId.asCString(), "imsiReport");
		return FALSE;
	}

	OssJson &msg = root["msg"];
	OssJson &imei = msg["imei"];
	OssJson &imsi = msg["imsi"];
	OssJson &beginTime = msg["beginTime"];
	OssJson &rat	 = msg["rat"];

	if ((imei.ValueType() != JSON_STRING_VAL) ||
		(imsi.ValueType() != JSON_STRING_VAL) ||
		(beginTime.ValueType() != JSON_STRING_VAL)||
		(rat.ValueType() != JSON_STRING_VAL))
	{
		printf("UeInfoManage::ParseUeInfo imei/imsi/beginTime/rat/ is error:%s\n",pcJson);
		return FALSE;
	}

	//判断imsi释放有错误
	//char* strImsi = (char*)imsi.asCString();
	//for (int i=0;i<15;i++)
	//{
	//	if (strImsi[i] < '0' || strImsi[i] > '9')
	//	{
	//		printf("UeInfoManage::ParseUeInfo ueinfo error:%s\n",pcJson);
	//		return FALSE;
	//	}
	//}
	//printf("imei:%s\n",imei.asCString());
	//printf("imsi:%s\n",imsi.asCString());
	//printf("deviceId:%s\n",deviceId.asCString());
	//printf("rat:%s\n",rat.asCString());
	//printf("beginTime:%s\n",beginTime.asCString());

	return TRUE;
}

void JsonOperatorPerformanceTesting(char* pcJson)
{
	DWord dwTick = OssGetTickCount();
	for (int i=0;i<TEST_COUNT;i++)
	{
		JsonOperatorTest(pcJson);
	}
	dwTick = OssGetTickCount() - dwTick;

	printf("执行 %d 次 Json解析，总计耗时%dms\n",TEST_COUNT,dwTick);
}

/**
 *		 赋值测试
 */
Bool JsonEqualTest(char *pcJson)
{
	OssJson root;
	root.ParseJson(pcJson);

	OssJson dst;

	dst = root;

	char rootJson[4096];
	char dstJson[4096];

	root.ToJsonString(rootJson,sizeof(rootJson));
	dst.ToJsonString(dstJson,sizeof(dstJson));

	if (OssStrcmp(rootJson,dstJson) == 0)
	{
		if (g_printSussess)
		{
			printf("赋值测试成功:\n\t%s\n",rootJson);
		}
	}
	else
	{
		printf("赋值测试失败:\n\t%s\n\t%s\n",rootJson,dstJson);
		return FALSE;
	}

	dst = "wjhlumei";
	dst.ToJsonString(dstJson,sizeof(dstJson));
	if (OssStrcmp(dstJson,"\"wjhlumei\"") == 0)
	{
		if (g_printSussess)
			printf("测试赋值成功:%s\n",dstJson);
	}
	else
	{
		printf("测试赋值失败:%s\n",dstJson);
		return FALSE;
	}

	dst = 132;
	dst.ToJsonString(dstJson,sizeof(dstJson));
	if (OssStrcmp(dstJson,"132") == 0)
	{
		if (g_printSussess)
			printf("测试赋值成功:%s\n",dstJson);
	}
	else
	{
		printf("测试赋值失败:%s\n",dstJson);
		return FALSE;
	}

	dst = 132.123;
	dst.ToJsonString(dstJson,sizeof(dstJson));
	if (OssStrcmp(dstJson,"132.123000") == 0)
	{
		if (g_printSussess)
			printf("测试赋值成功:%s\n",dstJson);
	}
	else
	{
		printf("测试赋值失败:%s\n",dstJson);
		return FALSE;
	}

	return TRUE;
}

void JsonEqualMemoryTest(char *pcJson)
{
	DWord dwTick = OssGetTickCount();
	for (int i=0;i<TEST_COUNT;i++)
	{
		JsonEqualTest(pcJson);
	}
	dwTick = OssGetTickCount() - dwTick;

	printf("执行 %d 次 Json赋值测试，总计耗时%dms\n",TEST_COUNT,dwTick);
}

void TestJson1()
{
	char* pJson = "{\"msgId\":\"trafficStaticRsp\",\"transactionId\":\"1\",\"deviceId\":\"TrafficStatic\",\"msg\":{\"resultType\":1,\"data\":{\"category\":[\"02月\",\"03月\",\"04月\",\"05月\",\"06月\",\"07月\",\"08月\",\"09月\",\"10月\",\"11月\",\"12月\",\"01月\"],\"legend\":[\"Lte1\",\"总量\"],\"series\":[{\"data\":[0,0,0,0,0,0,0,0,0,0,0,4384404],\"name\":\"Lte1\",\"type\":\"line\"},{\"data\":[0,0,0,0,0,0,0,0,0,0,0,4384404],\"name\":\"总量\",\"type\":\"line\"}]},\"message\":\"\",\"result\":true}}";

	OssJson oroot;

	int iError = oroot.ParseJson(pJson);
	if (iError != 0)
	{
		printf("OssJson strParam不是Json字符串:%s\n\t%s\n\n", pJson,pJson+iError);
	}
	else
	{
		printf("解析成功\n");
	}

	oroot["msg"]["resultType"].asInt();
}

void TestToJson()
{
	char* json = "{\"sessionId\":\"769695776E1A9014360570DF84BA8EB6\",\"msgId\":\"exportUserInfoReq\",\"transactionId\":\"4\""
		",\"deviceId\":\"UserManage\",\"msg\":{\"deptId\":17,}}";
	//json = "asdfse";
	OssJson root;

	if (root.ParseJson(json) != 0)
	{
		printf("json error\n");
		return ;
	}

	OssJson& msg=root["msg"];

	char acBuf[1024];
	OssMemset(acBuf,0,sizeof(acBuf));

	if (root.ToJsonString(acBuf,sizeof(acBuf)) > 0)
	{
		printf("tojson:%s\n",acBuf);
	}
	else
	{
		printf("tojson faield\n");
	}


}

void TestIntVal()
{
	char* json = "{\"msgId\":\"saveResult\",\"transactionId\":\"%d\",\"deviceId\":\"IUDdevice\""
		",\"msg\":{\"userId\":956,\"expression\":\"T:[1090]B[1091]\",\"pageSize\":200,\"pageIndex\":1,"
		"\"dataFileName\":\"并集运算2019-5-20 17-19-57\",\"caseId\":-2,\"reqType\":\"taskInsDiffReq\"}}";

	OssJson root;
	if (root.ParseJson(json) != 0)
	{
		printf("json error\n");
		return ;
	}

	OssJson& msg=root["msg"];//1参数检测
	OssJson &userId = msg["userId"];
	OssJson &expression = msg["expression"];
	OssJson &pageSize = msg["pageSize"];
	OssJson &pageIndex = msg["pageIndex"];
	OssJson &dataFileName = msg["dataFileName"];
	OssJson &caseId = msg["caseId"];
	OssJson &reqType = msg["reqType"];
	if (userId.ValueType() != JSON_INT_VAL
		|| expression.ValueType() != JSON_STRING_VAL
		|| pageSize.ValueType() != JSON_INT_VAL
		|| pageIndex.ValueType() != JSON_INT_VAL
		|| dataFileName.ValueType() != JSON_STRING_VAL
		|| caseId.ValueType() != JSON_INT_VAL
		|| reqType.ValueType() != JSON_STRING_VAL
		)
	{
		printf("IudOperator::SaveResultReq param err\n");
	}
	else
	{
		int iVal = caseId.asInt();
		printf("iVal = %d\n",iVal);
	}
}

void TestPushVal()
{
	OssJson json;

	json["wjh"] = "lumei";
	json.Push("lumei");
	
	OssJson val;
	val["wjh"] = "lumei";
	json.Push(val);

	for (int i=0;i<json.Size();i++)
	{
		OssJson &v = json[i];
		if (v.ValueType() == JSON_STRING_VAL)
		{
			printf("val:%s \t",v.asCString());
		}
		else if (v.ValueType() == JSON_OBJ_VAL)
		{
			printf("wjh=%s\n",v["wjh"].asCString());
		}
	}
}

void JsonTest1()
{
	TestPushVal();
	TestIntVal();
	TestToJson();
	TestJson1();


	g_printSussess = TRUE;

	//性能测试
	char *pcJson = "{\"msgId\":\"imsiReport\",\"transactionId\":\"0\",\"version\":\"1.0.0\",\"deviceId\":\"Lte3\","
		"\"msg\":{\"deviceId\":\"Lte3\",\"rat\":\"LTE\",\"beginTime\":\"20181218160944996\",\"imsi\":\"460020152499550\","
		"\"imei\":\"sfesdf\",\"longitude\":\"23.0000000\",\"latitude\":\"23.0000000\"}}";

	JsonEqualTest(pcJson);
	g_printSussess = FALSE;
	JsonEqualMemoryTest(pcJson);
#if 1
	CheckJson(pcJson,pcJson);
	pcJson = "{\"msgId\":\"imsiReport\",\"transactionId\":\"0\",\"version\":\"1.0.0\",\"deviceId\":\"Lte3\","
		"\"msg\":{\"deviceId\":\"Lte3\",\"rat\":\"LTE\",\"beginTime\":\"20181218160944996\",\"imsi\":\"460020152499550\","
		"\"imei\":\"\",\"longitude\":\"23.0000000\",\"latitude\":\"23.0000000\"}}";

	JsonOperatorTest(pcJson);
	JsonOperatorPerformanceTesting(pcJson);
	PerformanceTesting(pcJson);
#endif
#if 1
	g_printSussess = FALSE;
	do 
	{
		char *pcJsonTest = "{\"msgId\":\"deviceBootNotification\",\"transactionId\":\"0\",\"deviceId\":\"530ServerMaster\",\"msg\""
			":{\"version\":\"V2.0.0.0\",\"name\":\"zunYi530ServerMaster\",\"author\":\"wujianhuang\",\"date\":\"Sep 11 2018\","
			"\"desc\":\"创建530后台驱动 2017年6月29日\"}}";
		if (!CheckJson(pcJsonTest,pcJsonTest))
		{
			break;
		}

		if (!CheckJson("{ k  :{ad:123,吴建凰:卢梅,吴建凰:[1.123,false,{wjh:lumei},[]]}}"
			,"{\"k\":{\"ad\":123,\"吴建凰\":\"卢梅\",\"吴建凰\":[1.123000,false,{\"wjh\":\"lumei\"},[]]}}"))
		{
			break;
		}

		if (!CheckJson("{ 吴建凰:卢梅}","{\"吴建凰\":\"卢梅\"}"))
		{
			break;
		}

		if (!CheckJson("{ k  :{ad:123,bb:[1.123,false,{wjh:lumei},[]]}}","{\"k\":{\"ad\":123,\"bb\":[1.123000,false,{\"wjh\":\"lumei\"},[]]}}"))
		{
			break;
		}
		if (!CheckJson("{ k  :{ad:123,bb:[1.123,false,{wjh:lumei}]}}","{\"k\":{\"ad\":123,\"bb\":[1.123000,false,{\"wjh\":\"lumei\"}]}}"))
		{
			break;
		}
		if (!CheckJson("{ k  :{ad:123,bb:[1.123,false]}}","{\"k\":{\"ad\":123,\"bb\":[1.123000,false]}}"))
		{
			break;
		}

		if (!CheckJson("{ k  :{ad,123,[1.123,false]}}","{\"k\":[\"ad\",123,[1.123000,false]]}",FALSE))
		{
			break;
		}
		if (!CheckJson("{ \"k  :true  }","{\"k\":true}",FALSE))
		{
			break;
		}
		if (!CheckJson("{ k  :[ad,123,[1.123,false]]}","{\"k\":[\"ad\",123,[1.123000,false]]}"))
		{
			break;
		}

		if (!CheckJson("{ k  :[ad,123,1.123,false]}","{\"k\":[\"ad\",123,1.123000,false]}"))
		{
			break;
		}
		if (!CheckJson("{ k  :[ad,123,adl]}","{\"k\":[\"ad\",123,\"adl\"]}"))
		{
			break;
		}
		if (!CheckJson("{ k  :[]}","{\"k\":[]}"))
		{
			break;
		}
		if (!CheckJson("{ k  :[1:123,234,34]}","{\"k\":[\"1:123\",234,34]}"))
		{
			break;
		}

		if (!CheckJson("{ k  :[123,234,34]}","{\"k\":[123,234,34]}"))
		{
			break;
		}
		if(!CheckJson("{\"k\":v}","{\"k\":\"v\"}"))
		{
			break;
		}

		if (!CheckJson("{\"k\"  : v }","{\"k\":\"v\"}"))
		{
			break;
		}

		if (!CheckJson("{\" k\"  : v }","{\" k\":\"v\"}"))
		{
			break;
		}

		if (!CheckJson("{ k  : v }","{\"k\":\"v\"}"))
		{
			break;
		}

		if (!CheckJson("{ k\"  : v }","{\"k\\\"\":\"v\"}"))
		{
			break;
		}

		if (!CheckJson("{ \"k  : v }","{\"k\\\"\":\"v\"}",FALSE))
		{
			break;
		}

		if (!CheckJson("{k  : \"v\" }","{\"k\":\"v\"}"))
		{
			break;
		}

		if (!CheckJson("{k  : \"  v  \" }","{\"k\":\"  v  \"}"))
		{
			break;
		}

		//int型测试
		if (!CheckJson("{k  :123123}","{\"k\":123123}"))
		{
			break;
		}

		if (!CheckJson("{ k  :  123123  }","{\"k\":123123}"))
		{
			break;
		}

		if (!CheckJson("{ k  :  123.123  }","{\"k\":123.123000}"))
		{
			break;
		}

		if (!CheckJson("{ k  :  123.  123  }","{\"k\":\"123.  123\"}"))
		{
			break;
		}
		if (!CheckJson("{ k  :  123.  123  }","{\"k\":\"123.  123\"}"))
		{
			break;
		}

		if (!CheckJson("{ k  :  false  }","{\"k\":false}"))
		{
			break;
		}

		if (!CheckJson("{ k  :  true  }","{\"k\":true}"))
		{
			break;
		}
		if (!CheckJson("{ k  :true  }","{\"k\":true}"))
		{
			break;
		}

		if (!CheckJson("{ k  :\"true  }","{\"k\":true}",FALSE))
		{
			break;
		}

		if (!CheckJson("{ k  :true 12}","{\"k\":\"true 12\"}"))
		{
			break;
		}

		if (!CheckJson("{ k  :true,b:123,c:123.123,d:\"123\"  }","{\"k\":true,\"b\":123,\"c\":123.123000,\"d\":\"123\"}"))
		{
			break;
		}

		if (!CheckJson("{ k  :true 12,b:1 23,c:123.123,d:\" 123\"  }","{\"k\":\"true 12\",\"b\":\"1 23\",\"c\":123.123000,\"d\":\" 123\"}"))
		{
			break;
		}

		g_printSussess = TRUE;
	} while (false);

	if (g_printSussess)
	{
		printf("CheckJson 成功\n");
	}
	else
	{
		printf("CheckJson 失败\n");
	}
#endif
}

void JsonTest2()
{
	char *pcJsonStr = "{\"msgId\":\"parsedOrder\",\"tsId\":4,\"deviceId\":\"烫点订单接收模块/美团外卖\",\"from\":\"烫点订单解析/美团外卖\""
		",\"msg\":{\"length\":1552,\"vendor\":\"天禧麻辣烫\",\"platform\":\"美团外卖\",\"orderIndex\":2,\"orderTime\":\"2020-03-10 10:11:17\""
		",\"pockets\":[{\"pocketIndex\":1"
			",\"menus\":[{\"name\":\"玉米面\",\"num\":2,\"price\":6.000000}"
			",{\"name\":\"波波肠\",\"num\":1,\"price\":4.000000}"
			",{\"name\":\"日本豆腐\",\"num\":1,\"price\":3.500000}"
			",{\"name\":\"有机菜花\",\"num\":1,\"price\":3.000000}"
			",{\"name\":\"西兰花\",\"num\":1,\"price\":3.000000}"
			",{\"name\":\"土豆片\",\"num\":1,\"price\":2.800000}"
			",{\"name\":\"娃娃菜\",\"num\":1,\"price\":2.800000}"
			",{\"name\":\"小白菜\",\"num\":1,\"price\":2.700000}]}"
		",{\"pocketIndex\":-1,\"name\":\"其他\""	 
			",\"menus\":[{\"name\":\"配送费\",\"num\":0,\"price\":2.580000}"
			",{\"name\":\"[满25.0元减8.0元]\",\"num\":0,\"price\":-8.000000}"
			",{\"name\":\"[用户使用联盟津贴减2元]\",\"num\":0,\"price\":-2.000000}"
			",{\"name\":\"[减配送费3.0元]\",\"num\":0,\"price\":-2.580000}"
			",{\"name\":\"[用户使用了美团红包减7元]\",\"num\":0,\"price\":-7.000000}]}]"
		",\"tail\":\"顾客号码手机尾号9000虚拟号码17695486420 转 5223备用号码1 17694901465 转 8039\",\"result\":\"success\"}}";
	OssJson root;

	printf("parseJson :%d\n",root.ParseJson(pcJsonStr));

	OssJson copy;
	copy = root;

	char acBuff[10*1024];
	copy.ToJsonString(acBuff,sizeof(acBuff));
	printf("copy %s\n",acBuff);

	pcJsonStr = "{\"msgID\":\"123\",\"msg\":{}}";
	int iError = root.ParseJson(pcJsonStr);
	if (iError != 0)
	{
		printf("parseJson failed :%d\n", iError);
	}

	pcJsonStr = "[{\"msgID\":\"123\"},{\"msg\":{}}]";
	iError = root.ParseJson(pcJsonStr);
	if (iError != 0)
	{
		printf("parseJson failed :%d\n", iError);
	}
}

void JsonTestFree1()
{
	OssJson root;
	OssJson val;
	val[""] = 1;

	root.Push(val);

	root = "";
}

bool JsonTestVectorBytes()
{
	OssJson root;

	root["wjh"] = "lumei";

	std::vector<Byte> datas;
	datas.resize(30);
	memcpy(datas.data(), "wjhlumei",9);
	root["datas"].setValue(datas);

	std::vector<Byte> mdatas = root["datas"].asVectorByte();
	if (strcmp((const char*)datas.data(), (const char*)mdatas.data()) != 0)
	{
		printf("test error\n");
		return false;
	}

	char bcdString[1000];
	int iLen = root.ToJsonString(bcdString, sizeof(bcdString));
	printf("root json %d:%d-%s\n",iLen,strlen(bcdString), bcdString);

	OssJson copy;
	copy.ParseJson(bcdString);

	char copyBcdString[1000] = {0};
	iLen = root.ToJsonString(copyBcdString, sizeof(copyBcdString));
	printf("copy json %d:%d-%s\n", iLen, strlen(copyBcdString), copyBcdString);

	return true;
}

void testLeakMemory()
{
	OssJson initJson;
	if (initJson["id"].ValueType() != JSON_STRING_VAL)
	{
		initJson["id"] = "deviceMain";
	}
	if (initJson["drvDir"].ValueType() != JSON_STRING_VAL)
	{
		initJson["drvDir"] = "./drvs";
	}
	if (initJson["labelConfig"].ValueType() != JSON_STRING_VAL)
	{
		initJson["labelConfig"] = "./labelConfig.cfg";
	}
	if (initJson["needConsoleLog"].ValueType() != JSON_BOOLEAN_VAL)
	{
		initJson["needConsoleLog"] = true;
	}
}

int main(int argc, char* argv[])
{
	JsonTestVectorBytes();

	JsonTestFree1();

#if 1
	JsonTest2();
#endif
#if 1
	Test1();
	Test2_kv();
#endif

	testLeakMemory();
	printf("compete test\n");

	{
		OssJson initParam;
		initParam["labelConfig"] = "13123";
		initParam["needConsoleLog"] = true;
	}
	

	_CrtDumpMemoryLeaks();
	return 0;
}

